/*******************************************************************************
 * Package: com.hngtrust.iir.privatereport.controller
 * Type:    PrivateReportController
 * Date:    2021/9/14 10:27
 *
 * Copyright (c) 2021 HUANENG GUICHENG TRUST CORP.,LTD All Rights Reserved.
 *
 * You may not use this file except in compliance with the License.
 *******************************************************************************/
package com.hngtrust.iir.material.controller;

import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.hngtrust.framework.bind.ResponseInfo;
import com.hngtrust.framework.id.service.MyIdGenerator;
import com.hngtrust.framework.page.PageResult;
import com.hngtrust.framework.page.service.PageService;
import com.hngtrust.framework.security.util.SecurityUtils;
import com.hngtrust.iir.base.service.DictService;
import com.hngtrust.iir.base.service.IndustrySwService;
import com.hngtrust.iir.dto.ReqDTO;
import com.hngtrust.iir.material.controller.dto.*;
import com.hngtrust.iir.material.dto.MaterialRightDTO;
import com.hngtrust.iir.material.dto.PrivateMaterialUsersDTO;
import com.hngtrust.iir.material.entity.MaterialCollect;
import com.hngtrust.iir.material.entity.MaterialLog;
import com.hngtrust.iir.material.entity.MaterialRight;
import com.hngtrust.iir.material.entity.PrivateMaterial;
import com.hngtrust.iir.material.service.*;
import com.hngtrust.iir.report.dto.CountUser;
import com.hngtrust.iir.report.service.*;
import com.hngtrust.iir.user.entity.User;
import com.hngtrust.iir.util.DateUtils;
import com.tiger.util.MyHttpClient;
import com.tiger.web.annotation.UploadMapping;
import com.tiger.web.service.FileService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import jodd.util.StringUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.validation.Valid;
import java.io.File;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 内部资料controller
 *
 * @author Chaidd
 * @date 2021/11/08 3:51 下午
 */
@Slf4j
@RestController
@RequestMapping("/private-material")
@Api(tags = "内部资料")
public class PrivateMaterialController {

    @Value("${ai.selfPrivateReport.url}")
    private String aiUrl;

    @Value("${upload.material.minio}")
    private String minioUpload;

    @Value("${pageoffice.posyspath}")
    private String poSysPath;

    @Value("${tiger.minio.out.address}")
    private String url;

    //minio地址
    @Value("${tiger.minio.out.address}")
    private String minioAddress;

    @Autowired
    @Qualifier("minIoFileService")
    private FileService fileService;

    @Autowired
    private MaterialService materialService;

    @Autowired
    private MyIdGenerator myIdGenerator;

    @Autowired
    private PrivateReportService privateReportService;

    @Autowired
    private PrivateMaterialService privateMaterialService;

    @Autowired
    private MaterialRightBacService materialRightBacService;

    @Autowired
    private PageService pageService;

    @Autowired
    private MaterialRightService materialRightService;

    @Autowired
    private DictService dictService;

    @Autowired
    private MaterialCollectService materialCollectService;

    @Autowired
    private MaterialLogService materialLogService;

    @Autowired
    private IndustrySwService industrySwService;

    @ApiOperation(value = "上传文件")
    @UploadMapping("/upload-material")
    public ResponseInfo<UploadMaterialRespVO> uploadReport(@ApiParam("上传参数") @RequestParam(required = true) MultipartFile file) {
        try {
            long start = System.currentTimeMillis();
            MyHttpClient client = new MyHttpClient();
            ObjectMapper objectMapper = new ObjectMapper();
            String path = minioUpload + DateUtils.getTodayString() + "/";
            String directory = System.getProperty("java.io.tmpdir");
            User loginUser = (User) SecurityUtils.getLoginUser().getAdditionalInfo();

            String substring = file.getOriginalFilename().substring(file.getOriginalFilename().lastIndexOf("."));
            String fileName = loginUser.getId().toString() + substring;
            File tempFile = new File(directory, fileName);
            file.transferTo(tempFile);//保存文件
            String retPath = fileService.upload(tempFile, path, true);
            long size = file.getSize();

            System.out.println(System.currentTimeMillis() - start);

            UploadMaterialAIReqDTO bo = new UploadMaterialAIReqDTO();
            bo.setPathString(retPath);
            String s = null;
            try {
                 s = client.postJson(aiUrl, bo);
            }catch (Exception e){
                e.printStackTrace();
                ResponseInfo info = new ResponseInfo();
                info.setCode("1");
                info.setMessage("解析错误");
                return info;
            }


            System.out.println(System.currentTimeMillis() - start);

            JsonNode jsonNode = objectMapper.readTree(s);
            JsonNode data = jsonNode.get("data");
            objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
            UploadMaterialRespVO vo = objectMapper.readValue(data.toString(), UploadMaterialRespVO.class);
            vo.setSize(size);
            vo.setFileName(file.getOriginalFilename());
            vo.setFilePath(retPath);

            System.out.println(System.currentTimeMillis() - start);

            return new ResponseInfo(vo);
        } catch (Exception e) {
            e.printStackTrace();
            ResponseInfo info = new ResponseInfo();
            info.setCode("1");
            info.setMessage("上传失败");
            return info;
        }
    }


    @ApiOperation(value = "保存资料")
    @PostMapping("/save-material")
    public ResponseInfo<String> saveMaterial(@ApiParam("请求参数") @Valid @RequestBody SavePrivateMaterialReqVO vo) {
        PrivateMaterial material = new PrivateMaterial();
        vo.setId(myIdGenerator.nextId());
        if (vo.getRightTag() == 2) {
            MaterialRightVO vo1 = new MaterialRightVO();
            vo1.setReportId(vo.getId());
            vo1.setUserId(vo.getUserIds());
            materialRightBacService.addRight(vo1);

        }
        if (vo.getPages() == null) {
            material.setPages(0);
        }
        BeanUtils.copyProperties(vo, material);
        User loginUser = (User) SecurityUtils.getLoginUser().getAdditionalInfo();
        material.setCreateTime(new Date());
        material.setCreateUserId(loginUser.getId());
        material.setUpdateTime(new Date());

        material.setUpdateUserId(loginUser.getId());
        material.setComments(0);
        if (vo.getPublishTime() != null) {
            material.setPublishTime(new Date(vo.getPublishTime()));
        }
        material.setFileSize(vo.getSize());
        if (vo.getFileName().endsWith(".pdf") || vo.getFileName().endsWith(".xls") || vo.getFileName().endsWith(".xlsx") || material.getFileName().endsWith(".xlsm")) {
            material.setPdfPath(vo.getFilePath());
            materialService.createPrivateMaterial(material);
        }
        material.setIndustryId(industrySwService.queryByCode(vo.getIndustryCode()).getId());
        material.setStatus(0);
        if (material.getFileName().endsWith(".pdf"))
            material.setFileType(1);
        if (material.getFileName().endsWith(".xlsx") || material.getFileName().endsWith(".xlsm") || material.getFileName().endsWith(".xls"))
            material.setFileType(2);
        if (material.getFileName().endsWith(".doc") || material.getFileName().endsWith(".docx"))
            material.setFileType(3);
        privateMaterialService.add(material);
        MaterialLog log = new MaterialLog();
        log.setId(myIdGenerator.nextId());
        Date date = new Date();
        log.setCreateTime(date);
        log.setCreateUserId(loginUser.getId());
        log.setOptType("上传文件");
        log.setTitle(material.getTitle());
        log.setReportId(material.getId());
        materialLogService.add(log);
        return new ResponseInfo();
    }

    @ApiOperation(value = "修改前查询资料")
    @PostMapping("/update-select-material")
    public ResponseInfo<UpdatePrivateMaterialResqVO> updateSelectMaterial(@ApiParam("请求参数") @RequestBody UpdateSelectMaterialReqVO vo) {

        PrivateMaterial privateMaterial = privateMaterialService.queryById(vo.getId());
        UpdatePrivateMaterialResqVO updatePrivateMaterialResqVO = new UpdatePrivateMaterialResqVO();
        BeanUtils.copyProperties(privateMaterial, updatePrivateMaterialResqVO);
        updatePrivateMaterialResqVO.setSize(privateMaterial.getFileSize());
        updatePrivateMaterialResqVO.setPublishTime(privateMaterial.getPublishTime().getTime());
        MaterialRight materialRight = new MaterialRight();
        materialRight.setReportId(vo.getId());
        List<MaterialRightDTO> list = materialRightService.queryMaterialRights(materialRight);
        List<Long> userIdList = new ArrayList<>();
        if(list.size() > 0){
            for (int i = 0; i < list.size(); i++) {
                userIdList.add(list.get(i).getUserId());
            }
          updatePrivateMaterialResqVO.setUserIds(userIdList);
        }

        return new ResponseInfo<>(updatePrivateMaterialResqVO);
    }

    @ApiOperation(value = "修改资料")
    @PostMapping("/update-material")
    public ResponseInfo<String> updateMaterial(@ApiParam("请求参数") @Valid @RequestBody SavePrivateMaterialReqVO vo) {
        PrivateMaterial privateMaterial = new PrivateMaterial();
        privateMaterial.setId(vo.getId());
        Long reportId = vo.getId();
        //先根据资料id删除数据
        materialRightService.deleteRightByReportId(reportId);
        List<MaterialRight> materialRights = new ArrayList<>();
        List<Long> userId = vo.getUserIds();
        //新增所有数据
        if (userId != null && userId.size() > 0) {
            for (Long aLong : userId) {
                MaterialRight materialRight = new MaterialRight();
                materialRight.setId(myIdGenerator.nextId());
                materialRight.setReportId(vo.getId());
                materialRight.setUserId(aLong);
                materialRight.setCreateTime(new Date());
                User loginUser = (User) SecurityUtils.getLoginUser().getAdditionalInfo();
                materialRight.setCreateUserId(loginUser.getId());
                materialRights.add(materialRight);
            }
            materialRightService.addRightByReportId(materialRights);
        }

        if (vo.getPages() == null) {
            privateMaterial.setPages(0);
        }
        BeanUtils.copyProperties(vo, privateMaterial);
        User loginUser = (User) SecurityUtils.getLoginUser().getAdditionalInfo();
        privateMaterial.setUpdateTime(new Date());
        privateMaterial.setUpdateUserId(loginUser.getId());
        privateMaterial.setComments(0);
        if (vo.getPublishTime() != null) {
            privateMaterial.setPublishTime(new Date(vo.getPublishTime()));
        }

        privateMaterial.setFileSize(vo.getSize());
        privateMaterial.setRightTag(vo.getRightTag());
        privateMaterial.setDwonTag(vo.getDwonTag());
        privateMaterial.setIndustryId(industrySwService.queryByCode(vo.getIndustryCode()).getId());
        privateMaterial.setStatus(0);
        if (privateMaterial.getFileName().endsWith(".pdf"))
            privateMaterial.setFileType(1);
        if (privateMaterial.getFileName().endsWith(".xlsx") || privateMaterial.getFileName().endsWith(".xlsm") || privateMaterial.getFileName().endsWith(".xls"))
            privateMaterial.setFileType(2);
        if (privateMaterial.getFileName().endsWith(".doc") || privateMaterial.getFileName().endsWith(".docx"))
            privateMaterial.setFileType(3);
        privateMaterialService.modifyById(privateMaterial);

        //修改elk数据
        materialService.updateElkReport(vo);

        MaterialLog log = new MaterialLog();
        log.setId(myIdGenerator.nextId());
        Date date = new Date();
        log.setCreateTime(date);
        log.setCreateUserId(loginUser.getId());
        log.setOptType("修改资料");
        log.setTitle(privateMaterial.getTitle());
        log.setReportId(privateMaterial.getId());
        materialLogService.add(log);
        return new ResponseInfo();
    }

    @ApiOperation(value = "删除资料")
    @PostMapping("/delete-update-material")
    public ResponseInfo<String> deleteUpdateMaterial(@ApiParam("请求参数") @RequestBody UpdateSelectMaterialReqVO vo) {
        PrivateMaterial report = privateMaterialService.queryById(vo.getId());
        report.setId(vo.getId());

        privateMaterialService.updateDelete(report.getId());

        //修改elk数据
        materialService.deleteUpdateElkReport(vo);

        MaterialLog log = new MaterialLog();
        log.setId(myIdGenerator.nextId());
        Date date = new Date();
        log.setCreateTime(date);
        User loginUser = (User) SecurityUtils.getLoginUser().getAdditionalInfo();
        log.setCreateUserId(loginUser.getId());
        log.setOptType("删除资料");
        log.setTitle(report.getTitle());
        log.setReportId(report.getId());
        materialLogService.add(log);
        return new ResponseInfo();
    }



    @ApiOperation("上传资料列表")
    @PostMapping("/material-list-upload")
    public ResponseInfo<PageResult<MaterialListUploadRespVO>> materialListUpload(@ApiParam("请求参数") @RequestBody ReqDTO<PrivateMaterialUploadVO> vo) {
        PrivateMaterial privateMaterial = new PrivateMaterial();
        String name;
        if (!StringUtil.isBlank(vo.getContent().getName())) {
            name = "%" + vo.getContent().getName() + "%";
        } else {
            name = null;
        }
        privateMaterial.setFileName(vo.getContent().getName());
        Integer i;

        if (vo.getContent().getStatus() != 0) {
            i = vo.getContent().getStatus();
        } else {
            i = null;
        }

        User loginUser = (User) SecurityUtils.getLoginUser().getAdditionalInfo();
        privateMaterial.setCreateUserId(loginUser.getId());
        PageResult<PrivateMaterial> page = pageService.page(vo.getPageParam(), () -> privateMaterialService.query(name, i, loginUser.getId()));
        PageResult<MaterialListUploadRespVO> pageResult = new PageResult<>();
        pageResult.setPage(page.getPage());
        List<MaterialListUploadRespVO> list = new ArrayList<>();
        for (PrivateMaterial p : page.getRows()) {
            MaterialListUploadRespVO vo1 = new MaterialListUploadRespVO();
            vo1.setRightTag(p.getRightTag());
            vo1.setRight("拥有者");
            BeanUtils.copyProperties(p, vo1);
            Integer size = p.getFileSize();
            vo1.setPath(url + p.getFilePath());
            if(size != null){
                vo1.setFileSize(materialService.getPrintSize(size));
            }else{
                vo1.setFileSize(0+"B");
            }
            MaterialCollect materialCollect = new MaterialCollect();
            materialCollect.setReportId(p.getId());
            List<MaterialCollect> materialCollects = materialCollectService.queryByReportId(p.getId(),privateMaterial.getCreateUserId());
            if (materialCollects.isEmpty()) {
                vo1.setCollection(2);
            } else {
                vo1.setCollection(1);
            }
            //增加处理状态
            vo1.setStatus("完成");
            if (p.getFileType().equals(3) && null == p.getPdfPath()) { //word类型
                vo1.setStatus("处理中");
            }
            list.add(vo1);
        }
        list = list.stream().sorted((a, b) -> -a.getCreateTime().compareTo(b.getCreateTime())).collect(Collectors.toList());
        pageResult.setRows(list);
        return new ResponseInfo(pageResult);
    }

    @ApiOperation("作者")
    @PostMapping("/create-user")
    public ResponseInfo<List<CountUser>> createUser() {
        List<CountUser> countUsers = privateReportService.countUser();
        return new ResponseInfo(countUsers);
    }

    @ApiOperation(value = "查询资料页面上传者")
    @PostMapping("/select-elk-material")
    public ResponseInfo<List<PrivateMaterialUsersDTO>> selectElkMaterial() {

        List<PrivateMaterialUsersDTO> privateMaterialUsersDTOS = privateMaterialService.queryByPublishNames();

        return new ResponseInfo(privateMaterialUsersDTOS);
    }



}
